package com.jiangcheng.demo.websocket;

import org.mybatis.logging.Logger;
import org.mybatis.logging.LoggerFactory;

import javax.websocket.Session;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class PrivateLetterManager {
    private Logger logger = LoggerFactory.getLogger(PrivateLetterManager.class);
    /**
     * 保存WebSocket,key 是Id，value是Session
     */
    private ConcurrentHashMap<String, Session> concurrentMap = new ConcurrentHashMap<>();

    /**
     * 离线消息
     */
    private ConcurrentHashMap<String, List<WebSocketMessageEntity>> offlineMessage = new ConcurrentHashMap<>();

    /**
     * 添加客户端
     */
    public void addClient(String id, Session session) {
        System.out.println("有新客户端连接:  " + id);
        /**
         *  添加当前连接的客户端 谁用putIfAbsent: 如果已经存在则不会在插入数据 返回值如果为null 就说明之前没有这个key 可以添加
         */
        Session sessionIfAbsent = concurrentMap.putIfAbsent(id, session);
        // 如果已经存在了 就把当前的session关掉
        if (sessionIfAbsent != null) {
            try {
                session.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        System.out.println(sessionIfAbsent);
    }


    /**
     * 发送私信
     * 直接用id拿到对应的session 如发现有目标用户则给他发送消息实体类
     */
    public void sendMessage(WebSocketMessageEntity webSocketMessageEntity, Session mySession, Integer action) throws IOException {

        System.out.println("发送消息");
        if (action == 2) {
            for (Map.Entry<String, Session> map : concurrentMap.entrySet()) {
                Session session = map.getValue();
                /**
                 * 调用发送消息 工具方法 传入目标session 然后给目标session发送消息
                 */
                this.sendMessage(session, webSocketMessageEntity.toString());
            }
        } else {
            // 获取别人的session
            Session toSession = concurrentMap.get(webSocketMessageEntity.getToId());
            // 给发送人自己发送
            this.sendMessage(mySession, webSocketMessageEntity.toString());
            if (toSession == null) {
                if (webSocketMessageEntity.getMsg().equals("test")) {
                    return;
                }
                System.out.println("没有该用户，可能该用户已经离线");
                /**   1.记录下来接收消息的离线用户ID
                 *    2.再判断该离线用户是否已经有离线消息
                 *          有:
                 *              把该条消息添加进去
                 *          没有：
                 *              创建一个集合<webSocketMessageEntity>然后添加进去
                 */
                String targetId = webSocketMessageEntity.getToId();
                List<WebSocketMessageEntity> webSocketMessageEntities = offlineMessage.get(targetId);
                // 判断该用户是否已经有了离线消息
                if (webSocketMessageEntities != null) {
                    // 如果已经存在就把当前发送过来的消息添加进去
                    webSocketMessageEntities.add(webSocketMessageEntity);
                    // 把添加消息后集合覆盖掉之前的
                    offlineMessage.put(targetId, webSocketMessageEntities);
                } else {
                    // 如果不存在就创建
                    List<WebSocketMessageEntity> list = new ArrayList<WebSocketMessageEntity>();
                    // 再添加值进去
                    list.add(webSocketMessageEntity);
                    offlineMessage.putIfAbsent(targetId, list);
                }

                return;
            }

            /**
             * 调用发送消息 工具方法 传入目标session 然后给目标session发送消息
             */
            this.sendMessage(toSession, webSocketMessageEntity.toString());
        }

    }

    /**
     * 发送消息工具方法
     */
    public void sendMessage(Session session, String message) throws IOException {
        session.getBasicRemote().sendText(message);
    }

    /**
     * 客户端关闭
     */
    public void remove(String id) {
        concurrentMap.remove(id);
        System.out.println("客户端断开{" + id + "}");
    }

    /**
     * 是否有离线消息
     *
     * @param id
     */
    public void is_offline(String id) throws IOException {
        /**
         * 如果有离线消息就for循环发送到客户端
         */
        List<WebSocketMessageEntity> webSocketMessageEntities = offlineMessage.get(id);
        Session clientSession = concurrentMap.get(id);
        if (webSocketMessageEntities != null) {
            System.out.println("有离线消息");
            // 把每一条消息循环发送到客户端循环发送
            for (WebSocketMessageEntity webSocketMessageEntity : webSocketMessageEntities) {
                this.sendMessage(clientSession, webSocketMessageEntity.toString());
            }
        }
        // 发送完离线消息后清除该用户的离线消息
        offlineMessage.remove(id);
    }
}
